import os
from PySide6.QtWidgets import (
    QApplication,
    QFileDialog,
    QVBoxLayout,
    QHBoxLayout,
    QWidget,
)
from PySide6.QtGui import QIcon
from PySide6.QtCore import Qt
from qframelesswindow import FramelessWindow, StandardTitleBar
from qfluentwidgets import (
    PrimaryPushButton,
    PushButton,
    InfoBar,
    InfoBarPosition,
    ComboBox,
    setTheme,
    Theme,
    BodyLabel,
)
from ..data.database import db
from .settings_dialog import SettingsDialog
from ..core.builder import file_build, keil_build

script_dir = os.path.dirname(os.path.abspath(__file__))


class MainWindow(FramelessWindow):
    def __init__(self, app=None):
        super().__init__()
        setTheme(Theme.LIGHT)
        self.setTitleBar(StandardTitleBar(self))
        self.setStyleSheet(
            """
            MainWindow {
                background-color: #fafafa;
            }
            QLabel {
                color: #333333;
                font-size: 13px;
                font-weight: 500;
            }
        """
        )
        self.setWindowTitle("亮亮编译命令生成工具")
        self.titleBar.titleLabel.setStyleSheet(
            """
            QLabel{
                color: black;
                background: transparent;
                font: 15px 'STXingkai';
                padding: 0 4px
            }
        """
        )
        # 图标和字体文件现在应该相对于项目根目录
        root_dir = os.path.dirname(os.path.dirname(script_dir))
        self.setWindowIcon(QIcon(os.path.join(root_dir, "logo.ico")))
        self.setFixedSize(540, 160)
        self.titleBar.maxBtn.hide()
        self.windowEffect.disableMaximizeButton(self.winId())
        self.initUI()
        # 尝试从旧的 JSON 配置文件迁移数据
        old_json_path = os.path.join(root_dir, "config.json")
        db.migrate_from_json(old_json_path)
        # 清理无效的历史记录
        db.clean_invalid_history()
        # 从配置设置模式，这将触发 on_mode_changed
        # 并正确更新 UI 的其余部分，如历史记录。
        last_mode = db.get_config("last_mode", "从目录扫描")
        self.mode_selection_combo.blockSignals(True)
        self.mode_selection_combo.setCurrentText(last_mode)
        self.mode_selection_combo.blockSignals(False)
        self._update_ui_for_mode(last_mode)

    def initUI(self):
        # 创建主容器和主布局
        main_widget = QWidget(self)
        main_layout = QVBoxLayout(main_widget)
        main_layout.setContentsMargins(20, 15, 20, 15)
        main_layout.setSpacing(15)

        # 设置主容器位置
        main_widget.move(0, self.titleBar.height())
        main_widget.setFixedSize(self.width(), self.height() - self.titleBar.height())

        # 第一行：路径选择区域（仅输入框）
        self.path_line_edit = ComboBox()
        self.path_line_edit.setPlaceholderText("选择或拖入 Keil 项目文件或工作区目录")

        # 第二行：模式选择和按钮区域
        controls_frame = QWidget()
        controls_layout = QHBoxLayout(controls_frame)
        controls_layout.setContentsMargins(0, 0, 0, 0)
        controls_layout.setSpacing(10)

        mode_label = BodyLabel("生成模式:")
        mode_label.setFixedWidth(57)
        self.mode_selection_combo = ComboBox()
        self.mode_selection_combo.addItems(["从目录扫描", "从 Keil 项目"])
        self.mode_selection_combo.currentTextChanged.connect(self.on_mode_changed)

        self.select_button = PushButton("选择")
        self.select_button.setFixedSize(80, 35)
        self.select_button.clicked.connect(self.select_path)

        self.settings_button = PushButton("设置")
        self.settings_button.setFixedSize(80, 35)
        self.settings_button.clicked.connect(self.open_settings)

        self.run_button = PrimaryPushButton("生成")
        self.run_button.setFixedSize(80, 35)
        self.run_button.clicked.connect(self.run)

        controls_layout.addWidget(mode_label)
        controls_layout.addWidget(self.mode_selection_combo)
        controls_layout.addStretch(1)  # 将按钮推到右侧
        controls_layout.addWidget(self.select_button)
        controls_layout.addWidget(self.settings_button)
        controls_layout.addWidget(self.run_button)

        # 添加所有区域到主布局
        main_layout.addWidget(self.path_line_edit)
        main_layout.addWidget(controls_frame)
        main_layout.addStretch(1)  # 添加弹性空间

    def _update_ui_for_mode(self, text):
        if text == "从目录扫描":
            self.select_button.setText("选择目录")
        else:
            self.select_button.setText("选择文件")
        self.update_history_view()

    def on_mode_changed(self, text):
        self._update_ui_for_mode(text)
        # 保存新选择的模式
        db.set_config("last_mode", text)

    def open_settings(self):
        current_path = self.path_line_edit.text()
        # 检查是否为空路径或占位符文本
        placeholder_text = getattr(
            self.path_line_edit,
            "_placeholderText",
            "选择或拖入 Keil 项目文件或工作区目录",
        )
        if not current_path or current_path == placeholder_text:
            InfoBar.warning(
                title="无项目",
                content="请先选择一个项目或目录",
                orient=Qt.Horizontal,
                isClosable=False,
                position=InfoBarPosition.TOP,
                duration=2000,
                parent=self,
            )
            return

        self.save_history()  # 确保项目存在于历史记录中

        mode = self.mode_selection_combo.currentText()
        history_key = "scan" if mode == "从目录扫描" else "keil"
        history_list = db.get_history(history_key)
        current_settings = {}
        for item in history_list:
            if item["path"] == current_path:
                current_settings = item
                break

        dialog = SettingsDialog(self)
        dialog.general_settings_frame.show()
        if mode == "从目录扫描":
            dialog.wanted_frame.show()
            dialog.hated_frame.show()
            dialog.keil_args_frame.show()
            dialog.include_file_frame.show()
            dialog.setFixedSize(400, 580)
        else:
            dialog.keil_args_frame.show()
            dialog.keil_include_dirs_frame.show()
            dialog.keil_root_path_frame.show()
            dialog.include_file_frame.show()
            dialog.select_keil_root_path_button.show()
            dialog.setFixedSize(400, 550)

        dialog.set_settings(current_settings)

        if dialog.exec() == SettingsDialog.Accepted:
            new_settings = dialog.get_settings()
            # 保存最大历史记录数到全局配置
            max_history = dialog.max_history_records_spinbox.value()
            db.set_max_history_records(max_history)
            new_settings["path"] = current_path
            # 将更新的设置直接保存到数据库
            db.save_history(history_key, current_path, new_settings)

    def select_path(self):
        mode = self.mode_selection_combo.currentText()
        current_path = self.path_line_edit.text()

        # 如果当前路径是占位符文本，则清空
        placeholder_text = getattr(
            self.path_line_edit,
            "_placeholderText",
            "选择或拖入 Keil 项目文件或工作区目录",
        )
        if current_path == placeholder_text:
            current_path = ""

        history_key = "scan" if mode == "从目录扫描" else "keil"
        history_list = db.get_history(history_key)

        if not current_path and history_list:
            current_path = history_list[0]["path"]

        dialog = QFileDialog(self)
        if mode == "从目录扫描":
            dialog.setFileMode(QFileDialog.Directory)
            dialog.setOption(QFileDialog.ShowDirsOnly, True)
            dialog.setDirectory(current_path if os.path.isdir(current_path) else "")
        else:  # Keil 项目
            dialog.setFileMode(QFileDialog.ExistingFile)
            dialog.setNameFilter("Keil Project Files (*.uvprojx *.uvproj)")
            dialog.setDirectory(
                os.path.dirname(current_path) if os.path.isfile(current_path) else ""
            )

        if dialog.exec():
            selected_path = dialog.selectedFiles()[0].replace("\\", "/")
            self.path_line_edit.setText(selected_path)
            self.save_history()
            self.update_history_view()  # 刷新组合框中的历史记录

    def run(self):
        mode = self.mode_selection_combo.currentText()
        path = self.path_line_edit.text().replace("\\", "/")

        # 检查是否为空路径、占位符文本或路径不存在
        placeholder_text = getattr(
            self.path_line_edit,
            "_placeholderText",
            "选择或拖入 Keil 项目文件或工作区目录",
        )
        if not path or path == placeholder_text or not os.path.exists(path):
            InfoBar.warning(
                title="路径无效",
                content="请选择一个有效的目录或文件。",
                orient=Qt.Horizontal,
                isClosable=False,
                position=InfoBarPosition.TOP,
                duration=2000,
                parent=self,
            )
            return

        self.save_history()  # 运行前保存历史记录
        history_key = "scan" if mode == "从目录扫描" else "keil"
        history_list = db.get_history(history_key)
        settings = {}
        for item in history_list:
            if item["path"] == path:
                settings = item
                break

        try:
            if mode == "从目录扫描":
                file_build(path, settings)
            else:  # Keil 项目
                keil_build(path, settings)

            InfoBar.success(
                title="成功",
                content="compile_commands.json 已成功生成！",
                orient=Qt.Horizontal,
                isClosable=False,
                position=InfoBarPosition.TOP,
                duration=1500,
                parent=self,
            )
        except Exception as e:
            InfoBar.error(
                title="错误",
                content=str(e),
                orient=Qt.Horizontal,
                isClosable=False,
                position=InfoBarPosition.TOP,
                duration=3000,
                parent=self,
            )

    def save_default_settings(self, settings):
        mode = self.mode_selection_combo.currentText()
        mode_key = "scan" if mode == "从目录扫描" else "keil"
        db.set_default_settings(mode_key, settings)

    def update_history_view(self):
        mode = self.mode_selection_combo.currentText()
        history_key = "scan" if mode == "从目录扫描" else "keil"
        history_list = db.get_history(history_key)
        paths = [item["path"] for item in history_list]

        self.path_line_edit.clear()
        if paths:
            self.path_line_edit.addItems(paths)
            self.path_line_edit.setCurrentText(paths[0])
        else:
            # 当没有历史记录时，重新设置占位符
            self.path_line_edit.setCurrentText("")
            self.path_line_edit.setPlaceholderText(
                "选择或拖入 Keil 项目文件或工作区目录"
            )

    def save_history(self):
        current_path = self.path_line_edit.text().replace("\\", "/")
        # 检查是否为空路径或占位符文本
        placeholder_text = getattr(
            self.path_line_edit,
            "_placeholderText",
            "选择或拖入 Keil 项目文件或工作区目录",
        )
        if not current_path or current_path == placeholder_text:
            return

        mode = self.mode_selection_combo.currentText()
        history_key = "scan" if mode == "从目录扫描" else "keil"

        # 尝试从历史记录中获取现有项目
        history_list = db.get_history(history_key)
        existing_item = None
        for item in history_list:
            if item["path"] == current_path:
                existing_item = item
                break

        if existing_item:
            # 使用现有设置
            db.save_history(history_key, current_path, existing_item)
        else:
            # 使用默认设置创建新项目
            default_settings = db.get_default_settings(history_key)
            new_item = {"path": current_path}
            new_item.update(default_settings)

            if mode == "从 Keil 项目":
                # 如果默认根目录为空，则使用项目文件所在目录
                root_path = new_item.get("root_path", "")
                if not root_path:
                    root_path = os.path.dirname(current_path).replace("\\", "/")
                    new_item["root_path"] = root_path

            db.save_history(history_key, current_path, new_item)
